# 文件名: mv_contact.py
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtSql import QSqlDatabase, QSqlTableModel
from PyQt5.QtWidgets import *


class ContactsModel:
    def __init__(self):

        """Create and set up the model."""
        mydb = QSqlDatabase.addDatabase("QSQLITE")
        mydb.setDatabaseName('./contacts.sqlite')
        if not mydb.open():
            QMessageBox.critical(None, "QTableModel Example - Error!", "Database Error: %s" % mydb.lastError().databaseText(), )
        self.model = QSqlTableModel(None, mydb)
        self.model.setTable("contacts")  # 选择表名
        self.model.setEditStrategy(QSqlTableModel.OnFieldChange)
        self.model.select()  # 相当于执行select语句，把数据读入model
        headers = ("ID", "姓名", "工作岗位", "邮箱")
        for columnIndex, header in enumerate(headers):
            self.model.setHeaderData(columnIndex, Qt.Horizontal, header)

    def addContact(self, data):
        """Add a contact to the database."""
        rows = self.model.rowCount()
        self.model.insertRows(rows, 1)
        for column, field in enumerate(data):
            self.model.setData(self.model.index(rows, column + 1), field)
        self.model.submitAll()
        self.model.select()

    def deleteContact(self, row):
        """Remove a contact from the database."""
        self.model.removeRow(row)
        self.model.submitAll()
        self.model.select()

    def queryContact(self, condition):
        """ query contacts with condition to name field"""
        self.model.setFilter(condition)
        self.model.select()


class AddDialog(QDialog):
    """Add Contact dialog."""

    def __init__(self, parent=None):
        """Initializer."""
        super().__init__(parent=parent)
        self.setWindowTitle("Add Contact")
        self.vbox = QVBoxLayout()
        self.setLayout(self.vbox)
        self.data = None
        self.setupUI()

    def setupUI(self):
        """Setup the Add Contact dialog's GUI."""
        # Create line edits for data fields
        self.nameField = QLineEdit()
        self.nameField.setObjectName("Name")
        self.jobField = QLineEdit()
        self.jobField.setObjectName("Job")
        self.emailField = QLineEdit()
        self.emailField.setObjectName("Email")
        # Lay out the data fields
        layout = QFormLayout()
        layout.addRow("Name:", self.nameField)
        layout.addRow("Job:", self.jobField)
        layout.addRow("Email:", self.emailField)
        self.vbox.addLayout(layout)
        # Add standard buttons to the dialog and connect them
        self.buttonsBox = QDialogButtonBox(self)
        self.buttonsBox.setOrientation(Qt.Horizontal)
        self.buttonsBox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        self.buttonsBox.accepted.connect(self.accept)
        self.buttonsBox.rejected.connect(self.reject)
        self.vbox.addWidget(self.buttonsBox)

    def accept(self):
        """Accept the data provided through the dialog."""
        self.data = []
        for field in (self.nameField, self.jobField, self.emailField):
            if not field.text():
                QMessageBox.critical(self, "Error!", f"You must provide a contact's {field.objectName()}", )
                self.data = None  # Reset .data
                return
            self.data.append(field.text())
        if not self.data:
            return
        super().accept()


class MyWin(QMainWindow):
    def __init__(self, parent=None):
        super(MyWin, self).__init__()
        self.setWindowTitle("QTableView Example")
        self.resize(800, 400)
        # Set up the model
        self.ContactsModel = ContactsModel()
        # Set up the view
        self.view = QTableView()
        self.view.setModel(self.ContactsModel.model)
        self.view.resizeColumnsToContents()
        self.view.setSelectionBehavior(QAbstractItemView.SelectRows)
        # Create buttons
        self.addButton = QPushButton("添加记录")
        self.addButton.clicked.connect(self.openAddDialog)
        self.deleteButton = QPushButton("删除记录")
        self.deleteButton.clicked.connect(self.deleteContact)
        self.clearAllButton = QPushButton("删除所有")
        self.clearAllButton.clicked.connect(self.deleteAll)
        # Search
        self.formlayout = QFormLayout(self)
        self.qry_input_name = QLineEdit()
        self.qry_input_name.setMaximumWidth(120)
        self.button_search = QPushButton("查询", self)
        self.button_search.setCheckable(True)
        self.button_search.clicked.connect(self.queryContact)
        # 布局
        self.mywidget = QWidget()
        self.setCentralWidget(self.mywidget)
        hbox = QHBoxLayout(self.mywidget)
        vbox = QVBoxLayout(self.mywidget)
        vbox.addWidget(self.addButton)
        vbox.addWidget(self.deleteButton)
        vbox.addWidget(QLabel("姓名"))
        vbox.addWidget(self.qry_input_name)
        # vbox.addLayout(self.formlayout)
        vbox.addWidget(self.button_search)
        vbox.addStretch()
        vbox.addWidget(self.clearAllButton)
        hbox.addWidget(self.view)
        hbox.addLayout(vbox)
        self.mywidget.setLayout(hbox)

    def openAddDialog(self):
        """Open the Add Contact dialog."""
        dialog = AddDialog(self)
        if dialog.exec() == QDialog.Accepted:
            self.ContactsModel.addContact(dialog.data)
            self.view.resizeColumnsToContents()

    def deleteContact(self):
        """Delete the selected contact from the database."""
        row = self.view.currentIndex().row()
        if row < 0:
            return
        messageBox = QMessageBox.warning(self, "Warning!", "Do you want to remove the selected contact?", QMessageBox.Ok | QMessageBox.Cancel, )
        if messageBox == QMessageBox.Ok:
            self.ContactsModel.deleteContact(row)

    def deleteAll(self):
        """delete all records in the contacts table"""
        QMessageBox.warning(self, "Info!", "暂时不支持清除全部记录", QMessageBox.Ok, )

    def queryContact(self, checked):
        """Prepare query condition, call query method of ContactsModel"""
        print("checled status: ", checked)
        if checked:
            self.button_search.setText("取消查询")
            input = self.qry_input_name.text()
            query = f"name like '%{input}%'"
        else:
            query = f"name like '%%'"
            self.button_search.setText("查询")
            self.qry_input_name.setText('')
            # call ContactsModel's query method
        self.ContactsModel.queryContact(query)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = MyWin()
    win.show()
    sys.exit(app.exec_())
